<?php
/*
*All rights reserved: Json.
*Links:http://www.liyaoquan.cn.
*Links:http://imarkchina.cn.
*Links:http://www.imarkchina.cn.
*/

//根据配置来继承对应的数据库驱动
$eval = 'Class MemcacheDbDriver extends Db'.C('DB_DRIVER').'{}';
eval($eval);

Class DbMemcache extends MemcacheDbDriver {
	Private Static $_connect = array();

	Private Static $_instance = null;

	Public Static function getInstance() {
		if (is_null(self::$_instance)) self::$_instance = new self();
		return self::$_instance;
	}

	Private function _connect() {
		$servers = C('DB_MEMCACHE');
		$connectId = md5(serialize($servers));
		if (isset(self::$_connect[$connectId])) return self::$_connect[$connectId];
		if (!extension_loaded('memcache')) {
			throw new Exception(__METHOD__.' [没有安装memcache扩展模块]');
		}

		self::$_connect[$connectId] = new Memcache();
		if (is_array($servers)) {
			foreach ($servers as $server) {
				call_user_func_array(array(self::$_connect[$connectId], 'addServer'), $server);
				$stats = self::$_connect[$connectId]->getStats();
				if (!$stats) $connectError = true;
			}
		}
		if (isset($connectError)) throw new Exception(__METHOD__.' [连接memcache服务器失败]');
		J::debug('Memcache: 已开启');
		return self::$_connect[$connectId];
	}

	Public function query($sql, $method = '') {
		$method = strtolower($method);
		$table = $this->table;
		if ($method == 'fetch' || $method == 'fetchall' || $method == 'count') { //常规查询
			$data = $this->_get($sql);
			if ($data) return $data;
			$data = parent::query($sql, $method);
			$this->_add($table, $sql, $data);
			return $data;
		}
		if ($method == 'insert' || $method == 'update' || $method == 'delete') {
			$affectedRows = parent::query($sql, $method);
			if ($affectedRows > 0) {
				$this->_deletes($table);
				J::debug('清除表<b>'.$table.'</b>在Memcache中所有缓存!');
			}
			return $affectedRows;
		}
		return parent::query($sql);
	}

	Private function _addKey($table, $key) {
		$Memcache = $this->_connect();
		$keys = $Memcache->get($table);
		if (!$keys) $keys = array();
		if (!in_array($key, $keys)) {
			$keys[] = $key; //将新的key添加到本表的keys中
			$Memcache->set($table, $keys, MEMCACHE_COMPRESSED, 0);
			return true; //不存在返回true
		}
		return false; //存在返回false
	}

	Private function _add($table, $sql, $data) {
		$key = md5($sql);
		if ($this->_addKey($table, $key)) {
			$Memcache = $this->_connect();
			$Memcache->set($key, $data, MEMCACHE_COMPRESSED, 0);
		}
	}

	Private function _get($sql) {
		$key = md5($sql);
		$Memcache = $this->_connect();
		return $Memcache->get($key);
	}

	Private function _deletes($table) {
		$Memcache = $this->_connect();
		$keys = $Memcache->get($table);
		if ($keys) {
			foreach ($keys as $key) $Memcache->delete($key, 0); //0 表示立刻删除
		}
		$Memcache->delete($table, 0);
	}
}